[Update] การจัดการ laravel.log ด้วย CloudWatch Logs ใน Elastic Beanstalk
สวัสดีครับ POP จากบริษัท Classmethod (Thailand) ครับ
เราสามารถจัดการ laravel.log ด้วย CloudWatch Logs เพื่อดูประวัติการใช้งานผ่าน Log ที่เป็นการสร้าง EC2 ในรูปแบบ Auto Scaling บน Elastic Beanstalk ได้
สิ่งที่ต้องมี
สร้างสภาพแวดล้อมสำหรับสร้างไฟล์โปรเจกต์ ZIP
หากยังไม่มีโปรเจกต์ Laravel ให้สร้างโปรเจกต์ตามนี้ได้เลย แต่ถ้ามีโปรเจกต์อยู่แล้วข้ามไปสร้างไฟล์ ZIP โดยดูที่ลิงก์บทความถัดไปได้เลย (ครั้งนี้จะใช้ Instance ชื่อ tinnakorn-develop
)
แล้วสร้างไฟล์ ZIP โดยดูตัวอย่างที่ลิงก์บทความนี้ (ยังไม่ต้องรันคำสั่งสร้างไฟล์ ZIP)
ดาวน์โหลดไฟล์โปรเจกต์ ZIP
Click to download: laravel10-sample.zip
เมื่อดาวน์โหลดไฟล์เสร็จแล้ว ให้แตกไฟล์และคัดลอกโฟลเดอร์ .ebextensions
ไปเพิ่มในโปรเจกต์ที่จะ Deploy ไปยัง Elastic Beanstalk ซึ่งในโฟลเดอร์จะมีไฟล์ดังนี้
- .ebextensions
- 01_swap.config
- 02_timezone.config
- 03_laravel_folders.config
- 04_mariadb.config
การเตรียมไฟล์ CloudWatch Log Config ใน Laravel
สร้างไฟล์: [.ebextensions/05_cloudwatchlog.config
] และคัดลอก Code นี้วางที่ไฟล์ 05_cloudwatchlog.config
packages: yum: amazon-cloudwatch-agent: [] files: "/home/ec2-user/cloudwatch_log_setup.sh": mode: "000755" owner: root group: root content: | #!/bin/bash export $(cat /opt/elasticbeanstalk/deployment/env | grep -v ^# | xargs); export INSTANCE_ID=`cat /var/lib/cloud/data/instance-id` aws logs create-log-group --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --region ${AWS_DEFAULT_REGION} aws logs put-retention-policy --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --retention-in-days 30 --region ${AWS_DEFAULT_REGION} aws logs create-log-stream --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --log-stream-name ${INSTANCE_ID} --region ${AWS_DEFAULT_REGION} echo -n "" >> /etc/amazon/amazon-cloudwatch-agent/amazon-cloudwatch-agent.d/laravel_log printf '{ "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "/var/app/current/storage/logs/laravel*.log", "log_group_name": "/%s/%s/laravel_log", "log_stream_name": "%s", "auto_removal": true, "retention_in_days": 30, "timestamp_format": "%%Y-%%m-%%d %%H:%%M:%%S", "timezone": "Local" } ] } } } } ' ${APP_NAME} ${APP_ENV} ${INSTANCE_ID} > /etc/amazon/amazon-cloudwatch-agent/amazon-cloudwatch-agent.d/laravel_log container_commands: "01_cloudwatchlog_install": command: | echo `date`." 01_cloudwatchlog_install" >> /var/log/ebextensions_test.log /home/ec2-user/cloudwatch_log_setup.sh systemctl restart amazon-cloudwatch-agent.service systemctl enable amazon-cloudwatch-agent.service
เมื่อเตรียมไฟล์การตั้งค่า CloudWatch Log เสร็จแล้ว ให้ทำการสร้างไฟล์ ZIP โดยรันคำสั่งนี้
รันคำสั่งล้างแคชต่างๆ เตรียมไว้
php artisan optimize:clear
รันคำสั่งด้านล่างนี้เพื่อสร้างไฟล์ zip ตามสิ่งที่เขียนไว้ข้างต้นนี้ (*เปลี่ยน "[deploy_file_name.zip]" ให้เป็นชื่อไฟล์ของคุณ เช่น laravel10-cloudwatchlog.zip
เป็นต้น)
zip -r
: คำสั่งสร้างไฟล์ zip-x
: คำสั่งยกเว้นโฟลเดอร์หรือไฟล์เพื่อไม่ให้รวมใน zip
zip -r [deploy_file_name.zip] * .editorconfig .styleci.yml .ebextensions .platform -x \*/.git/\* vendor/\* node_modules/\* public/build/\* public/hot/\* public/storage/\* storage/\*.key storage/framework/sessions/\* storage/framework/views/\* Homestead.json Homestead.yaml npm-debug.log yarn-error.log .idea .vscode .env \*.zip
สร้าง Resources ที่จำเป็นสำหรับ Elastic Beanstalk
- สร้าง Service role และ Instance profile ที่ใช้สำหรับ Elastic Beanstalk ใน IAM
- สร้าง Key Pair สำหรับ Elastic Beanstalk
- สร้าง Security Group สำหรับ Elastic Beanstalk
สร้าง Service role และ Instance profile ที่ใช้สำหรับ Elastic Beanstalk ใน IAM
ครั้งนี้จะสร้าง Service role และ Instance profile ที่ใช้สำหรับ Elastic Beanstalk ใน IAM โดยจะเพิ่มสิทธิ์สำหรับจัดการ CloudWatch Logs ลงใน Instance profile เพื่อให้ Instance ที่สร้างใน Elastic Beanstalk สามารถจัดการ CloudWatch Logs ได้โดยแนะนำให้กำหนดชื่อและ Permissions ตาม Documentation ของ AWS และกำหนด Permissions ที่ชื่อ CloudWatchLogsFullAccess
เพิ่มเติมดังนี้
IAM Role Name | Permissions |
---|---|
tinnakorn-cloudwatchlog-ec2-role | AWSElasticBeanstalkWebTier |
AWSElasticBeanstalkWorkerTier | |
AWSElasticBeanstalkMulticontainerDocker | |
CloudWatchLogsFullAccess |
ขั้นตอนนี้ให้สร้าง Role ดังกล่าวโดยดูตัวอย่างที่ลิงก์ด้านล่างนี้โดยเพิ่มสิทธิ์ CloudWatchLogsFullAccess
เข้าไปใน Role สำหรับ Instance profile ด้วย และสำหรับชื่อ IAM Role สามารถตั้งชื่อได้ตามต้องการ
สร้าง Key Pair สำหรับ Elastic Beanstalk
ครั้งนี้จะสร้าง Key Pair ชื่อว่า tinnakorn-cloudwatchlog-eb
ดูตัวอย่างที่นี่เฉพาะหัวข้อนี้: การสร้าง Key Pair
ตัวอย่างตั้งค่าการสร้าง Key Pairs ในบทความนี้
※Create Key pairs
Name:tinnakorn-cloudwatchlog-eb
Private key file format:.ppk
สร้าง Security Group สำหรับ Elastic Beanstalk
ครั้งนี้จะสร้าง Security Group ชื่อว่า: tinnakorn-cloudwatchlog-eb
เข้ามาที่ Service Amazon EC2 แล้วคลิก Security Groups
จากเมนูด้านซ้ายในหัวข้อ "▼ Network & Security"
คลิก Create security group
เมื่อเข้ามาหน้า Create security group แล้วให้ตั้งค่า Basic details:
・Security group name: tinnakorn-cloudwatchlog-eb
(ชื่ออะไรก็ได้)
・Description: tinnakorn-cloudwatchlog-eb
(ป้อนอะไรก็ได้)
จากนั้นเลื่อนลงมาด้านล่างสุด คลิก Create security group
การสร้าง Security Groups ใช้สำหรับ Elastic Beanstalk เสร็จเรียบร้อยแล้ว ทำขั้นตอนถัดไปได้เลย
สร้าง Environment สำหรับ CloudWatch Log
หากเรามี Environment ที่ Deploy สำหรับ Laravel อยู่แล้ว สามารถ Copy การตั้งค่าและสร้าง Environment จาก Saved configuration ใน Application ของเราได้โดยดูตัวอย่างได้ที่ลิงก์ด้านล่างนี้
หากไม่มี Environment ดังกล่าวให้ทำตามขั้นตอนด้านล่างนี้
ดูวิธีการสร้าง Environment สำหรับ CloudWatch Log ด้วย Auto Scaling ตามลิงก์ด้านล่างนี้ เนื่องจากเป็นการตั้งค่าที่เหมือนกัน
ดูตัวอย่างที่นี่: สร้าง Environment สำหรับ Auto Scaling (ดูตัวอย่างการตั้งค่าด้านล่างนี้ประกอบด้วย เนื่องจากมีบางส่วนที่ตั้งค่าไม่เหมือนกัน)
ตัวอย่างครั้งนี้จะสร้าง Environment โดยใช้ชื่อดังนี้
Environment name:tinnakorn-cloudwatchlog-eb
EC2 key pair:tinnakorn-cloudwatchlog-eb
EC2 security groups:tinnakorn-cloudwatchlog-eb
สำหรับ Step 2 - Configure service access เปลี่ยน EC2 instance profile ให้เป็นสำหรับ
CloudWatch Log
ดังนี้
・เลือก EC2 instance profile ที่สร้างเมื่อสักครู่ ครั้งนี้คือ tinnakorn-cloudwatchlog-ec2-roleสำหรับ Step 4 - optional: Configure instance traffic and scaling
・ไม่ต้องตั้งค่าเปิดใช้งานStickiness
ในหัวข้อ Processes เนื่องจากต้องการทดสอบ Error Log ที่ถูกส่งจาก Instance ไปยัง CloudWatch Logสำหรับ Step 5 - optional: Configure updates, monitoring, and logging ให้เปลี่ยนการตั้งค่าในส่วนของ Environment properties ให้เป็นสำหรับ
CloudWatch Log
ดังนี้
・APP_ENV =cloudwatchlog
・APP_NAME =tinnakorn
・คลิกNext
ไปยัง Step 6: Review
แล้วดำเนินการ Step 6: Review
・ตรวจสอบการตั้งค่าตั้งแต่ "Step 1 - Step 5"
・คลิกSubmit
ด้านล่างสุด แล้วรอสักครู่
ถ้าเสร็จแล้วให้คลิกลิงก์เปิดหน้าเว็บไซต์โปรเจกต์ของเราจากหน้า Environment (ลิงก์นี้เป็นแค่ตัวอย่าง)
http://tinnakorn-cloudwatchlog-eb.ap-southeast-1.elasticbeanstalk.com/
ตรวจสอบ CloudWatch Log
ไปที่ Service [CloudWatch > Log groups]
ทำการตรวจสอบ Log ดังนี้:
ค้นหาชื่อของเรา เช่น /tinnakorn/cloudwatchlog
แล้วคลิกเข้าไป (นี่คือตัวแปรสภาพแวดล้อมที่ถูกใช้งาน ซึ่งเป็น /APP_NAME/APP_ENV
นั่นเอง)
เมื่อเข้ามาแล้วดูที่ Log streams จะเห็นว่ามี Instance ID แสดงขึ้นมา 2 ตัวตามที่กำหนดไว้ใน Elastic Beanstalk
ซึ่งเราสามารถ Copy Instance ID จากที่นี่ไปค้นหาในหน้า Instance ได้
ทีนี้ให้คลิกเข้าไปดูในแต่ละ Instance ได้เลย
Instance ID ของบทความนี้: i-00ab2472f62135222
, i-0e84af5b8940bab63
จะเห็นว่าไม่มีข้อมูลแสดงใน Log events เพราะว่ายังไม่มี Error
ทดสอบ Error Log ใน CloudWatch Log
กลับมาที่หน้าเว็บไซต์โปรเจกต์ของเรา แล้วเปิดหน้าเว็บอะไรก็ได้ที่ทำให้เกิด Error เพื่อให้บันทึก Log ไปยัง laravel.log เช่น
http://tinnakorn-cloudwatchlog-eb.ap-southeast-1.elasticbeanstalk.com/customer/3
ไปที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log > i-your_instance_id]
จะเห็นว่ามีข้อมูล Error Log แสดงขึ้นมาแล้ว
Terminate Instance และตรวจสอบ CloudWatch Log
มาที่ Service [EC2 > Instance] แล้วทำการ Terminate instance ตัวไหนก็ได้สัก 1 ตัว
เช่น i-00ab2472f62135222
แล้วรอจนกว่า Instance state เป็น Terminate
เมื่อ Instance state เป็น Terminate แล้วให้กดปุ่ม Reload
จะเห็นว่ามี Instance ใหม่เพิ่มขึ้นมา 1 ตัว นั่นก็คือ i-00f477fcd99cf242e
ทีนี้ให้มาที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log]
จะเห็นว่า Log stream ของ Instance ID: i-00f477fcd99cf242e
เพิ่มขึ้นมา ซึ่งยังไม่มีข้อมูล Error Log (กรณีที่ต้องการดู Log ของ Instance ID ที่ Terminate ไปแล้ว สามารถคลิกเข้าไปที่ Instance ID นั้นได้เลย)
ไปที่หน้าเว็บไซต์โปรเจกต์ที่ Error ของเรา แล้วทำการ Reload ประมาณ 2-3 ครั้ง
จากนั้นกลับมาที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log] อีกครั้งแล้วทำการ Reload
ถ้า Last event time ในแถวของ Instance ID ตัวใหม่แสดงวันที่และเวลาขึ้นมาแล้ว ให้คลิกเข้าไปได้เลย
จะเห็นว่ามีข้อมูล Error Log แสดงขึ้นมาแล้ว เพียงเท่านี้เราก็สามารถดูข้อมูล Log ใน Instance ของเราได้โดยไม่ต้องเข้าไปใน Linux และรันคำสั่งให้ยุ่งยากอีกต่อไป
สรุป
ผมได้มีโอกาสใช้ CloudWatch Log แล้วทำให้ผมรู้สึกว่าเวลาจะดูข้อมูล Error, ข้อมูลการเชื่อมต่อ หรือประวัติการใช้งานต่างๆ ก็ไม่ต้องไปรันคำสั่งใน Server EC2 ทุกครั้งให้ยุ่งยาก และตั้งแต่ได้รู้จักกับ Service CloudWatch แล้วทำให้ผมได้เห็นถึงความสะดวกในการตรวจสอบข้อมูลที่เรียกว่า Log คือเราสามารถเข้าไปดูใน Service CloudWatch ได้เลยนั่นเอง
นอกจากนี้ต่อให้เราทำการ Terminate Instance ไปแล้วเราก็ยังสามารถดูประวัติการใช้งานย้อนหลังของ Instance นั้นใน CloudWatch Log ได้อีกด้วย
บทความที่เกี่ยวข้อง
- ทดลอง Deploy Laravel ด้วย Elastic Beanstalk และลองเชื่อมต่อกับ RDS
- การตั้งค่าที่จำเป็นเพื่อ Deploy Laravel ด้วย Elastic Beanstalk
- การสร้าง Role ใน IAM
- วิธี Copy การตั้งค่า Environment ใน Elastic Beanstalk และเริ่มต้นระบบ
- วิธีการใช้ ELB (ALB) ใน Elastic Beanstalk
- การสร้าง CloudWatch Log เพื่อใช้งานใน EC2
- วิธีการใช้ ELB (ALB) ใน Elastic Beanstalk